﻿using System.Diagnostics;

namespace RegularlyBackupFiles
{
    internal class Program
    {
        static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            App.Init();

            Console.CancelKeyPress += (s, e) =>
            {
                e.Cancel = true;
                manualResetEvent.Set();
            };

            using var timer = new Timer(state =>
            {
                try
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    App.Logger.Information($"开始处理同步复制从【{App.Settings.OldPath}】到【{App.Settings.NewPath}】");
                    DoCopy(App.Settings.OldPath);
                    if (App.Settings.IsSyncDelete)
                    {
                        App.Logger.Information($"开始处理同步删除从【{App.Settings.OldPath}】验证【{App.Settings.NewPath}】");
                        DoDelete(App.Settings.NewPath);
                    }
                    stopwatch.Stop();
                    App.Logger.Information($"共处理了【{TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).ToStringFormat()}】");
                }
                catch (Exception ex)
                {
                    App.Logger.Error(ex.Message);
                }
            }, null, 0, 1000 * 60 * 60 * App.Settings.Cycle);

            App.OnConfChange(() =>
            {
                timer.Change(0, 1000 * 60 * 60 * App.Settings.Cycle);
            });

            manualResetEvent.WaitOne();
        }

        static void DoCopy(string oldDic)
        {
            if (Directory.Exists(oldDic) && Directory.EnumerateFileSystemEntries(oldDic).Any())
            {

                var newDic = $"{App.Settings.NewPath}{oldDic[App.Settings.OldPath.Length..]}";
                // 创建新路径
                if (Directory.Exists(newDic) == false)
                {
                    App.Logger.Information($"创建文件夹【{newDic}】");
                    Directory.CreateDirectory(newDic);
                }

                var files = Directory.GetFiles(oldDic).OrderBy(f => f);
                foreach (var file in files)
                {
                    string newFile = $"{App.Settings.NewPath}{file[App.Settings.OldPath.Length..]}";
                    if (File.Exists(file) == false)
                    {
                        App.Logger.Error($"文件【{file}】不存在");
                    }
                    else if (File.Exists(newFile) == false || File.GetLastWriteTime(file) != File.GetLastWriteTime(newFile))
                    {
                        App.Logger.Information($"复制文件【{file}】到【{newFile}】");
                        try
                        {
                            File.Copy(file, newFile, true);
                        }
                        catch (Exception ex)
                        {
                            App.Logger.Error(ex.Message);
                        }
                    }
                    else
                    {
                        App.Logger.Information($"跳过已存在未修改的文件【{file}】");
                    }
                }

                var dics = Directory.GetDirectories(oldDic).OrderBy(d => d);
                foreach (var d in dics)
                {
                    DoCopy(d);
                }

            }
            else
            {
                App.Logger.Information($"配置的需要备份的文件夹不存在文件【{oldDic}】");
                try
                {
                    if (Directory.Exists(oldDic))
                    {
                        App.Logger.Information($"删除不存在文件的文件夹【{oldDic}】");
                        Directory.Delete(oldDic);
                    }
                }
                catch (Exception ex)
                {
                    App.Logger.Error(ex.Message);
                }
            }

        }

        static void DoDelete(string newDic)
        {
            if (Directory.Exists(newDic))
            {
                var dics = Directory.GetDirectories(newDic).OrderBy(d => d);
                foreach (var d in dics)
                {
                    DoDelete(d);
                }

                var files = Directory.GetFiles(newDic).OrderBy(f => f);

                var oldDic = $"{App.Settings.OldPath}{newDic[App.Settings.NewPath.Length..]}";
                if (Directory.Exists(oldDic))
                {
                    foreach (var file in files)
                    {
                        string oldFile = $"{App.Settings.OldPath}{file[App.Settings.NewPath.Length..]}";
                        if (File.Exists(file) == false)
                        {
                            App.Logger.Error($"文件【{file}】不存在");
                        }
                        else if (File.Exists(oldFile) == false)
                        {
                            App.Logger.Information($"删除文件【{file}】");
                            try
                            {
                                File.Delete(file);
                            }
                            catch (Exception ex)
                            {
                                App.Logger.Error(ex.Message);
                            }
                        }
                        else
                        {
                            App.Logger.Information($"跳过存在的文件【{file}】");
                        }
                    }
                }
                else
                {
                    try
                    {
                        foreach (var file in files)
                        {
                            if (File.Exists(file))
                            {
                                App.Logger.Information($"删除文件【{file}】");
                                try
                                {
                                    File.Delete(file);
                                }
                                catch (Exception ex)
                                {
                                    App.Logger.Error(ex.Message);
                                }
                            }
                            else
                            {
                                App.Logger.Error($"文件【{file}】不存在");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        App.Logger.Error(ex.Message);
                    }
                }

                if (Directory.Exists(newDic) && Directory.EnumerateFileSystemEntries(newDic).Any() == false)
                {
                    App.Logger.Information($"删除文件夹【{newDic}】");
                    try
                    {
                        Directory.Delete(newDic);
                    }
                    catch (Exception ex)
                    {
                        App.Logger.Error(ex.Message);
                    }
                }
            }
            else
            {
                App.Logger.Error("备份的文件夹不存在");
            }
        }
    }
}
